/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */

#include "M2ModelInfo.h"

#include "Logger.h"
#include "WOWUtil.h"
#include "WOWArchive.h"
#include "ChrRacesDbc.h"
#include "ChrSecsDbc.h"
#include "ChrFaceHairStylDbc.h"
#include "ChrHairGeoDbc.h"

namespace GNgine
{
	CharDetails::CharDetails()
	{
	}

	CharDetails::CharDetails(Ogre::uint charRace,Ogre::uint charGender)
		: race(charRace),gender(charGender)
	{
		
		// Enable the use of NPC skins if its  a goblin.
		if (race==9){
			useNPC=1;
		}else{
			useNPC=0;
		}

		// If its a troll/tauren/dranei/naga/broken, show the feet (dont wear boots)
		if (race==6 || race==8 || race==11 || race==13 || race==14) {
			showFeet = true;
		}else{
			showFeet = false;
		}

		maxSkinColor=GNgChrRacesDbc.getRecordCount(race,gender,TEXTURE_TYPE_SKIN,0,useNPC);
		maxFaceType=GNgChrSecsDbc.getRecordCount(race, gender, TEXTURE_TYPE_FACE, 0, useNPC);

		maxHairColor = GNgChrRacesDbc.getRecordCount(race, gender, TEXTURE_TYPE_HAIR, 0, 0);
		maxFacialHair = GNgChrFaceHairStylDbc.getRecordCount(race, gender);
		maxFacialColor = maxHairColor;

		maxHairStyle = GNgChrHairGeoDbc.getRecordCount(race,gender);

		if (maxFaceType==0) maxFaceType = 1;
		if (maxSkinColor==0) maxSkinColor = 1;
		if (maxHairColor==0) maxHairColor = 1;
		if (maxHairStyle==0) maxHairStyle = 1;
		if (maxFacialHair==0) maxFacialHair = 1;
		
		
		skinColor = 0;//randint(0, maxSkinColor-1);
		faceType = 0;//randint(0, maxFaceType-1);
		hairColor = 0;//randint(0, maxHairColor-1);
		hairStyle = 0;//randint(0, maxHairStyle-1);
		facialHair = 0;//randint(0, maxFacialHair-1);
		hairStyle=1;

		facialColor = hairColor;

		// Reset submeshes
		for (int i=0; i<NUM_M2_SUBMESH; i++) {
			submeshes[i] = 1;
		}
		submeshes[1] = submeshes[2] = submeshes[3] = 0;

		if (showEars) {
			submeshes[7] = 2;
		}

		CharFaceHairRecord* facialHairRecord=GNgChrFaceHairStylDbc.getRecord(race,gender,facialHair);	
		if(facialHairRecord!=0){
			submeshes[1]=facialHairRecord->geoset100;
			submeshes[2]=facialHairRecord->geoset200;
			submeshes[3]=facialHairRecord->geoset300;
		}

	}

	M2ModelInfo::M2ModelInfo(M2File* m2File)
		: _m2File(m2File),_isCharacter(false)
	{
		_path=_m2File->getFileName();
		WowModelType type=getWOWModelTypeByPath(_path);
		if(type==WOW_MODEL_TYPE_CHARACTER){
			_isCharacter=true;
			size_t p1 = _path.find_first_of('/', 0);
			size_t p2 = _path.find_first_of('/', p1+1);
			size_t p3 = _path.find_first_of('/', p2+1);

			_raceName = _path.substr(p1+1,p2-p1-1);
			_genderName = _path.substr(p2+1,p3-p2-1);
			
			_gender = (_genderName == "female" || _genderName == "Female" || _genderName == "FEMALE") ? 1 : 0;
			ChrRacesRecord* record= GNgChrRacesDbc.getRecord(_raceName);
			if(record==0){
				_isCharacter=false;
			}
			_race = record->raceId;
		}

		initCharDetails();
		//must behide init character details
		initTex();
		
	}

	

	M2ModelInfo::M2ModelInfoMap M2ModelInfo::_list;
	M2ModelInfo::~M2ModelInfo()
	{
	}

	void M2ModelInfo::initCharDetails()
	{
		_details=CharDetails(_race,_gender);
		
	}

	void M2ModelInfo::initTex()
	{
		_m2TexDefs=_m2File->getTexDefs();
		_m2TexCount=_m2File->getTexCount();
		if(_m2TexCount<=0){
			return;
		}
		
		
		for (int i=0; i<_m2TexCount; i++) {
			if(_m2TexDefs[i].type==TEXTURE_FILENAME){
				std::string texName=_m2File->getTexName(i);
				_texNames.push_back(texName);
			}
		}

		if(_isCharacter){			
			initCharBodyTex();	
			initCharHairTex();
		}

	}


	void M2ModelInfo::initCharBodyTex()
	{
		CharSectionRecord* record=0;
		CharTexLayer layer;

		//body
		record=GNgChrSecsDbc.getRecord(_race,_gender,TEXTURE_TYPE_SKIN,0,_details.skinColor);
		if(record){
			layer.fileName=GNgChrSecsDbc.getTex1Path(record);
			layer.region=TEX_REGION_BASE;
			_layers.push_back(layer);
		}

		// underwear
		record=GNgChrSecsDbc.getRecord(_race,_gender,TEXTURE_TYPE_UNDERWEAR,0,_details.skinColor);
		if(record){
			layer.fileName=GNgChrSecsDbc.getTex1Path(record);
			layer.region=TEX_REGION_PELVIS_UPPER;
			_layers.push_back(layer);

			layer.fileName=record->texture2;
			layer.region=TEX_REGION_TORSO_UPPER;
			_layers.push_back(layer);
		}

		//face
		record=GNgChrSecsDbc.getRecord(_race,_gender,TEXTURE_TYPE_FACE,0,_details.facialColor);
		if(record){
			layer.fileName=GNgChrSecsDbc.getTex1Path(record);
			layer.region=TEX_REGION_FACE_LOWER;
			_layers.push_back(layer);

			layer.fileName=GNgChrSecsDbc.getTex2Path(record);
			layer.region=TEX_REGION_FACE_UPPER;
			_layers.push_back(layer);
		}

		// facial hair
		record=GNgChrSecsDbc.getRecord(_race,_gender,TEXTURE_TYPE_FACIAL_HAIR,0,0);
		if(record){
			layer.fileName=GNgChrSecsDbc.getTex1Path(record);
			layer.region=TEX_REGION_FACE_LOWER;
			_layers.push_back(layer);

			layer.fileName=GNgChrSecsDbc.getTex1Path(record);
			layer.region=TEX_REGION_FACE_UPPER;
			_layers.push_back(layer);
		}
		
	}

	//hair using another material
	void M2ModelInfo::initCharHairTex()
	{
		CharSectionRecord* record=0;
		CharTexLayer layer;
		record= GNgChrSecsDbc.getRecord(_race,_gender,TEXTURE_TYPE_HAIR,_details.hairStyle,_details.hairColor);
		char* texPath=GNgChrSecsDbc.getTex1Path(record);
		if(strcmp(texPath,"")!=0){
			_hairTexturePath=texPath;
			//
		}else{//Let's try with hair style #1.
			record= GNgChrSecsDbc.getRecord(_race,_gender,TEXTURE_TYPE_HAIR,1,_details.hairColor);
			texPath=GNgChrSecsDbc.getTex1Path(record);
			if (strcmp(texPath,"")!=0) {
				//
				_hairTexturePath=texPath;
			}
		}
	}

	void M2ModelInfo::initCharTex2()
	{
		CharSectionRecord* hairRecord=0;
		CharSectionRecord* bodyRecord=0;
		CharTexLayer hairLayer;
		CharTexLayer bodyLayer;

		for (int i=0; i<_m2TexCount; i++) {
			if (_m2TexDefs[i].type == TEXTURE_HAIR){
				hairRecord=GNgChrSecsDbc.getRecord(_race,_gender,TEXTURE_TYPE_HAIR,0,0);
				
				hairLayer.fileName=GNgChrSecsDbc.getTex1Path(hairRecord);
				hairLayer.region=TEX_REGION_BASE;
				
				
			}else if(_m2TexDefs[i].type == TEXTURE_BODY){
				bodyRecord=GNgChrSecsDbc.getRecord(_race,_gender,TEXTURE_TYPE_SKIN,0,0);
				bodyLayer.fileName=GNgChrSecsDbc.getTex1Path(bodyRecord);
				bodyLayer.region=TEX_REGION_BASE;
				
			}else if(_m2TexDefs[i].type == TEXTURE_CAPE){
				
			}else if(_m2TexDefs[i].type == TEXTURE_FUR){
				
			}else if(_m2TexDefs[i].type == TEXTURE_ARMORREFLECT){
				
			}else if(_m2TexDefs[i].type == TEXTURE_GAMEOBJECT1){
				
			}else if(_m2TexDefs[i].type == TEXTURE_GAMEOBJECT2){
				
			}else if(_m2TexDefs[i].type == TEXTURE_GAMEOBJECT3){
				
			}
		}

		if(hairRecord){
			_texNames.push_back(hairLayer.fileName);
		}
		if(bodyRecord){
			_texNames.push_back(bodyLayer.fileName);
		}
	}
}
